package com.practice.dataStructure.list;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
/**
 *
 * @param <E>
 */
public class ArrayList<E> implements List<E>{

    private static final int DEFAULT_CAPACITY = 10;


    private Object[] table;

    private int size;


    public ArrayList() {
        table = new Object[DEFAULT_CAPACITY];
        size = 0;
    }
    public ArrayList(int capacity) {

        table = new Object[capacity];
        size = 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Iterator<E> iterator() {
        return new ArrayListIterator();
    }

    class ArrayListIterator implements Iterator<E>{

        int cursor;

        @Override
        public boolean hasNext() {
            if(cursor < size){
                return true;
            }
            return false;
        }

        @Override
        public E next() {
            if(cursor >= size){
                throw new NoSuchElementException("Index: " + cursor + ", Size: " + size);
            }
            E element = (E) table[cursor++];
            return element;
        }
    }

    @Override
    public void add(E element) {
        if(size == table.length){
            resize();
        }
        table[size++] = element;
    }

    private void resize(){
        Object[] newTable = new Object[table.length * 2];
        // 这是一个native方法，内存层面的拷贝，效率很高
        System.arraycopy(table,0,newTable,0,table.length);
        table = newTable;
    }

    @Override
    public void add(int index, E element) {
        if(index < 0 || index > size){
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        if(size == table.length){
            resize();
        }
        System.arraycopy(table,index,table,index+1,size-index);
        table[index] = element;
        size++;
    }

    @Override
    public E get(int index) {
        if(index < 0 || index >= size){
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        return (E) table[index];
    }

    @Override
    public E set(int index, E element) {
        if(index < 0 || index >= size){
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E oldValue = (E) table[index];
        table[index] = element;
        return oldValue;
    }

    @Override
    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E oldValue = (E) table[index];
        System.arraycopy(table, index + 1, table, index, size - index - 1);
        // 防止内存泄漏
        table[--size] = null;
        return oldValue;
    }

    @Override
    public boolean remove(E element) {
        for(int i=0;i<size;i++){
            if(Objects.equals(element,table[i])){
                remove(i);
                return true;
            }
        }
        return false;
    }
}
